package org.vectrics.common.reporting;

import javax.servlet.*;
import javax.servlet.http.*;

import java.io.*;
import java.util.*;
import org.apache.log4j.Category;
import org.vectrics.common.reporting.pdf.*;
import org.vectrics.struts.HttpRequestConverter;
import org.vectrics.struts.Request;
import org.vectrics.user.ServiceRequestWriter;

import javax.naming.InitialContext;
import org.vectrics.DataException;
import org.vectrics.VectricsException;



public abstract class ReportServlet extends HttpServlet {
    private static final String CONTENT_TYPE = "text/html";
    private static Category log = Category.getInstance(ReportServlet.class);
    private boolean initialized = false;

    
    protected abstract ReportManager getReportManager() throws DataException;

    
    /**Initialize global variables*/
    public void init() throws ServletException {
    	super.init();
        log.debug("RecruiterServlet initializing.");
        initialized = true;
    }

    /**Process the HTTP Get request*/
    public void service(HttpServletRequest httpRequest, HttpServletResponse response) throws ServletException, IOException {
    	log.debug("service() - handling request for PDF report");
    	if (initialized == false) {
    		init();
    	}
    	
    	Request request = HttpRequestConverter.convertRequest(httpRequest);
    	ServiceRequestWriter requestWriter = new ServiceRequestWriter();
    	requestWriter.save(request);

		String awtToolKit = System.getProperty("awt.toolkit");
		String awtGraphicEnv = System.getProperty("java.awt.graphicsenv");
		String awtFont = System.getProperty("java.awt.fonts");
		log.debug("GRAPHICS: awt.toolkit = " + awtToolKit);
		log.debug("GRAPHICS: java.awt.graphicsenv = " + awtGraphicEnv);
		log.debug("GRAPHICS: java.awt.fonts = " + awtFont);

		byte[] reportBytes;
		try {
			InitialContext context = new InitialContext();
			Enumeration envEnum = context.getEnvironment().elements();
			while (envEnum.hasMoreElements()) {
				envEnum.nextElement();
			}
		}
		catch (Exception ex) {
			log.error("Exception getting initial context",ex);
		}
		
		
		String reportParam = request.getParameter("report");
		if (reportParam == null) {
			throw new ServletException("Report type not specified sith 'report' parameter");
			/*
			log.debug("Report param is null");
			ReportManager reportManager = null;
			try {
				reportManager = getReportManager();
			}
			catch (DataException de) {
				log.error("DataException acquiring RecruitManager", de);
				throw new ServletException("DataException acquiring RecruitManager", de);
				
			}
			String formPath = request.getRequestURI();

		
			if (request.getParameter("test") != null) {
				reportBytes =  reportManager.makeTestBytes(request, formPath, this.getServletContext());
			}
			else {
				reportBytes =  reportManager.makeReportBytes(request, formPath, this.getServletContext());
			}
			*/
		}
		else {
			log.debug("Report param = " + reportParam);
			try {
				Date now = new Date();
				long time = now.getTime();
				ByteArrayOutputStream outStream = new ByteArrayOutputStream();
				
				BaseReport report = this.getReportManager().createReport(request, outStream);	
				
				report.build(outStream);

				if (log.isDebugEnabled()) {
					log.debug("Output stream length = " + outStream.size());
					log.debug("Converting output stream to byte array");
				}
				reportBytes = outStream.toByteArray();
				
			}
			catch (VectricsException ve) {
				throw new ServletException("VectricsException building report", ve);
			}
			catch (Exception ex) {
				throw new ServletException("Exception building report", ex);
			}
						
		}

		
		Date now = new Date();
		long time = now.getTime();
		
		log.debug("Setting content type");
		response.setContentType("application/pdf");
		
		log.debug("Writing bytes to response");
		log.debug("Size of byte array = " + reportBytes.length);
		response.getOutputStream().write(reportBytes);
		response.setContentLength(reportBytes.length);
		
		log.info("Flushing response");
		response.getOutputStream().flush();
		
		log.info("finished");
		
    }


}